#pragma once

#include "asmCalc.h"

/*********   8   *********/

//math
static void add_8(  struct instance* this );
static void sub_8(  struct instance* this );
static void mul_8(  struct instance* this );
static void imul_8( struct instance* this );
static void div_8(  struct instance* this );
static void idiv_8( struct instance* this );
static void neg_8(  struct instance* this );

//logic
static void and_8( struct instance* this );
static void not_8( struct instance* this );
static void or_8(  struct instance* this );
static void xor_8( struct instance* this );

//shift
static void shl_8( struct instance* this );
static void shr_8( struct instance* this );
static void sal_8( struct instance* this );
static void sar_8( struct instance* this );
static void rol_8( struct instance* this );
static void ror_8( struct instance* this );

//other
static void fake_bswap_8( struct instance* this );
static void fake_movsx_8( struct instance* this );

static const struct host_asm_ops ops8 = {
	
	.regSize = 8,
	
	//math
	.add  = add_8,
	.sub  = sub_8,
	.mul  = mul_8,
	.imul = imul_8,
	.div  = div_8,
	.idiv = idiv_8,
	.neg  = neg_8,
	
	//logic
	.and  = and_8,
	.not  = not_8,
	.or   = or_8,
	.xor  = xor_8,
	
	//shift
	.shl = shl_8,
	.shr = shr_8,
	.sal = sal_8,
	.sar = sar_8,
	.rol = rol_8,
	.ror = ror_8,
	
	//other
	.bswap = fake_bswap_8,
	.movsx = fake_movsx_8
};

/*********   16   *********/

//math
static void add_16(  struct instance* this );
static void sub_16(  struct instance* this );
static void mul_16(  struct instance* this );
static void imul_16( struct instance* this );
static void div_16(  struct instance* this );
static void idiv_16( struct instance* this );
static void neg_16(  struct instance* this );

//logic
static void and_16( struct instance* this );
static void not_16( struct instance* this );
static void or_16(  struct instance* this );
static void xor_16( struct instance* this );

//shift
static void shl_16( struct instance* this );
static void shr_16( struct instance* this );
static void sal_16( struct instance* this );
static void sar_16( struct instance* this );
static void rol_16( struct instance* this );
static void ror_16( struct instance* this );

//other
static void xchg_16( struct instance* this );
static void movsx_16( struct instance* this );

static const struct host_asm_ops ops16 = {
	
	.regSize = 16,
	
	//math
	.add  = add_16,
	.sub  = sub_16,
	.mul  = mul_16,
	.imul = imul_16,
	.div  = div_16,
	.idiv = idiv_16,
	.neg  = neg_16,
	
	//logic
	.and  = and_16,
	.not  = not_16,
	.or   = or_16,
	.xor  = xor_16,
	
	//shift
	.shl = shl_16,
	.shr = shr_16,
	.sal = sal_16,
	.sar = sar_16,
	.rol = rol_16,
	.ror = ror_16,
	
	//other
	.bswap = xchg_16,
	.movsx = movsx_16
};

/*********   32   *********/

//math
static void add_32(  struct instance* this );
static void sub_32(  struct instance* this );
static void mul_32(  struct instance* this );
static void imul_32( struct instance* this );
static void div_32(  struct instance* this );
static void idiv_32( struct instance* this );
static void neg_32(  struct instance* this );

//logic
static void and_32( struct instance* this );
static void not_32( struct instance* this );
static void or_32(  struct instance* this );
static void xor_32( struct instance* this );

//shift
static void shl_32( struct instance* this );
static void shr_32( struct instance* this );
static void sal_32( struct instance* this );
static void sar_32( struct instance* this );
static void rol_32( struct instance* this );
static void ror_32( struct instance* this );

//other
static void bswap_32( struct instance* this );
static void movsx_32( struct instance* this );

static const struct host_asm_ops ops32 = {
	
	.regSize = 32,
	
	//math
	.add  = add_32,
	.sub  = sub_32,
	.mul  = mul_32,
	.imul = imul_32,
	.div  = div_32,
	.idiv = idiv_32,
	.neg  = neg_32,
	
	//logic
	.and  = and_32,
	.not  = not_32,
	.or   = or_32,
	.xor  = xor_32,
	
	//shift
	.shl = shl_32,
	.shr = shr_32,
	.sal = sal_32,
	.sar = sar_32,
	.rol = rol_32,
	.ror = ror_32,
	
	//other
	.bswap = bswap_32,
	.movsx = movsx_32
};


#if defined( __x86_64__ )
/*********   64   *********/

//math
static void add_64(  struct instance* this );
static void sub_64(  struct instance* this );
static void mul_64(  struct instance* this );
static void imul_64( struct instance* this );
static void div_64(  struct instance* this );
static void idiv_64( struct instance* this );
static void neg_64(  struct instance* this );

//logic
static void and_64( struct instance* this );
static void not_64( struct instance* this );
static void or_64(  struct instance* this );
static void xor_64( struct instance* this );

//shift
static void shl_64( struct instance* this );
static void shr_64( struct instance* this );
static void sal_64( struct instance* this );
static void sar_64( struct instance* this );
static void rol_64( struct instance* this );
static void ror_64( struct instance* this );

//other
static void bswap_64( struct instance* this );
static void movsx_64( struct instance* this );

static const struct host_asm_ops ops64 = {
	
	.regSize = 64,
	
	//math
	.add  = add_64,
	.sub  = sub_64,
	.mul  = mul_64,
	.imul = imul_64,
	.div  = div_64,
	.idiv = idiv_64,
	.neg  = neg_64,
	
	//logic
	.and  = and_64,
	.not  = not_64,
	.or   = or_64,
	.xor  = xor_64,
	
	//shift
	.shl = shl_64,
	.shr = shr_64,
	.sal = sal_64,
	.sar = sar_64,
	.rol = rol_64,
	.ror = ror_64,
	
	//other
	.bswap = bswap_64,
	.movsx = movsx_64
};

#endif //x86-64

/*********   ops  list   *********/

static const struct host_asm_ops* const opsList[] = { 
#if defined( __x86_64__ )
	&ops64,
#endif
	&ops32,
	&ops16,
	&ops8,
	NULL 
};
